package com.hcrazy.manchester.app.services;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.mail.DefaultAuthenticator;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.joda.time.DateTime;

import com.hcrazy.manchester.app.jdbc.BookFoodDAO;
import com.hcrazy.manchester.app.jdbc.CouponDAO;
import com.hcrazy.manchester.app.jdbc.FriendDAO;
import com.hcrazy.manchester.app.jdbc.LiveAddressDAO;
import com.hcrazy.manchester.app.jdbc.LiveSimpleDAO;
import com.hcrazy.manchester.app.jdbc.MessageDAO;
import com.hcrazy.manchester.app.jdbc.PostDAO;
import com.hcrazy.manchester.app.jdbc.RentDAO;
import com.hcrazy.manchester.app.jdbc.SecondaryDAO;
import com.hcrazy.manchester.app.jdbc.TopicDAO;
import com.hcrazy.manchester.app.jdbc.UserDAO;
import com.hcrazy.manchester.app.jdbc.UserInfoDAO;
import com.hcrazy.manchester.app.pojo.ErrorMsg;
import com.hcrazy.manchester.app.pojo.ForumRule;
import com.hcrazy.manchester.app.pojo.Friend;
import com.hcrazy.manchester.app.pojo.Message;
import com.hcrazy.manchester.app.pojo.PageModel;
import com.hcrazy.manchester.app.pojo.User;
import com.hcrazy.manchester.app.pojo.UserGroup;
import com.hcrazy.manchester.app.pojo.UserInfo;
import com.hcrazy.manchester.app.utils.Constant;
import com.hcrazy.manchester.app.utils.Log;
import com.hcrazy.manchester.app.utils.MD5Util;

public class UserService {

	private UserDAO userDAO;
	
	private RentDAO rentDAO;
	
	private SecondaryDAO secondaryDAO;
	
	private CouponDAO couponDAO;
	
	private BookFoodDAO bookFoodDAO;
	
	private LiveAddressDAO liveAddressDAO;
	
	private LiveSimpleDAO liveSimpleDAO;
	
	private MessageDAO messageDAO;
	
	private TopicDAO topicDAO;
	
	private PostDAO postDAO;
	
	public CouponDAO getCouponDAO() {
		return couponDAO;
	}

	public void setCouponDAO(CouponDAO couponDAO) {
		this.couponDAO = couponDAO;
	}

	public BookFoodDAO getBookFoodDAO() {
		return bookFoodDAO;
	}

	public void setBookFoodDAO(BookFoodDAO bookFoodDAO) {
		this.bookFoodDAO = bookFoodDAO;
	}

	public LiveAddressDAO getLiveAddressDAO() {
		return liveAddressDAO;
	}

	public void setLiveAddressDAO(LiveAddressDAO liveAddressDAO) {
		this.liveAddressDAO = liveAddressDAO;
	}

	public LiveSimpleDAO getLiveSimpleDAO() {
		return liveSimpleDAO;
	}

	public void setLiveSimpleDAO(LiveSimpleDAO liveSimpleDAO) {
		this.liveSimpleDAO = liveSimpleDAO;
	}

	public UserDAO getUserDAO() {
		return userDAO;
	}

	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
	}
	
	public RentDAO getRentDAO() {
		return rentDAO;
	}

	public void setRentDAO(RentDAO rentDAO) {
		this.rentDAO = rentDAO;
	}

	public SecondaryDAO getSecondaryDAO() {
		return secondaryDAO;
	}

	public void setSecondaryDAO(SecondaryDAO secondaryDAO) {
		this.secondaryDAO = secondaryDAO;
	}
	
	private UserInfoDAO userInfoDAO;

	public UserInfoDAO getUserInfoDAO() {
		return userInfoDAO;
	}

	public void setUserInfoDAO(UserInfoDAO userInfoDAO) {
		this.userInfoDAO = userInfoDAO;
	}
	
	private FriendDAO friendDAO;

	public FriendDAO getFriendDAO() {
		return friendDAO;
	}

	public void setFriendDAO(FriendDAO friendDAO) {
		this.friendDAO = friendDAO;
	}

	public MessageDAO getMessageDAO() {
		return messageDAO;
	}

	public void setMessageDAO(MessageDAO messageDAO) {
		this.messageDAO = messageDAO;
	}

	public TopicDAO getTopicDAO() {
		return topicDAO;
	}

	public void setTopicDAO(TopicDAO topicDAO) {
		this.topicDAO = topicDAO;
	}

	public PostDAO getPostDAO() {
		return postDAO;
	}

	public void setPostDAO(PostDAO postDAO) {
		this.postDAO = postDAO;
	}

	/**
	 * 会员注册
	 * @param user
	 * @return
	 * @throws Exception
	 */
	public Object register(User user,Object validateCode) throws Exception{

		if(user.getType() == Constant.REGISTER_BY_EMAIL){
			if(null == user.getEmail() || "".equals(user.getEmail())){
				return new ErrorMsg(Constant.MEMBER_REGISTER_EMAIL_NULL,"邮箱不能为空！");
			}
			//验证邮箱格式
			if(!user.getEmail().matches(Constant.EMAIL_PATTERN)){
				return new ErrorMsg(Constant.MEMBER_REGISTER_EMAIL_INVALIDE,"邮箱格式不正确！");
			}
			//验证邮箱是否已经注册过
			if(userDAO.isRegisteredEmail(user.getEmail())){
				return new ErrorMsg(Constant.MEMBER_REGISTER_EMAIL_EXIST,"该邮箱已经被占用!");
			}
			
		}else if(user.getType() == Constant.REGISTER_BY_PHONE){
			if(null == user.getPhone() || "".equals(user.getPhone())){
				return new ErrorMsg(Constant.MEMBER_REGISTER_PHONE_NULL,"手机号不能为空！");
			}
			//验证手机号
			if(!user.getPhone().matches(Constant.PHONE_PATTERN)){
				return new ErrorMsg(Constant.MEMBER_REGISTER_PHONE_INVALIDE,"手机号码格式不正确！");
			}
			//验证手机号是否已经使用过
			if(userDAO.isRegisteredPhone(user.getPhone())){
				return new ErrorMsg(Constant.MEMBER_REGISTER_PHONE_EXIST,"手机号已经被占用！");
			}
		}
		
		if(null == user.getUsername() || "".equals(user.getUsername())){
			return new ErrorMsg(Constant.MEMBER_REGISTER_USERNAME_NULL,"昵称不能为空！");
		}
		if(null == user.getPassword() || "".equals(user.getPassword())){
			return new ErrorMsg(Constant.MEMBER_REGISTER_PASSWORD_NULL,"密码不能为空！");
		}
		
		//验证用户名唯一性
		User u = userDAO.getUserByUsername(user.getUsername());
		if(null != u && u.getUserId() > 0){
			return new ErrorMsg(Constant.MEMBER_REGISTER_USERNAME_EXIST,"用户名已经被占用！");
		}
		
		//判断验证码是否正确
//		ErrorMsg msg = new ErrorMsg();
//		if(null == validateCode){
//			msg.setCode(Constant.MEMBER_REGISTER_VALIDATECODE);
//			msg.setMsg("验证码不正确！");
//			return msg;
//		}
//		if(!user.getValidateCode().equals(validateCode.toString())){
//			msg.setCode(Constant.MEMBER_REGISTER_VALIDATECODE);
//			msg.setMsg("验证码不正确！");
//			return msg;
//		}		
		
		//对密码进行加密
		user.setPassword(MD5Util.fromStringToMD5(user.getPassword()));
		
		//设置注册时间
		DateTime dt = new DateTime();
		String registerTime = dt.toString("yyyy-MM-dd hh:mm:ss");
		user.setRegisterTime(registerTime);
		
		try {
			//注册，增加经验值；增加卡包容量；增加用户组
			Map<Integer,ForumRule> rules = InitService.forumRules;
			ForumRule rule = rules.get(Constant.RULE_TYPE_REGISTER);
			if(null != rule && rule.getDisabled() == 0){
				user.setExp(rule.getRuleValue());//注册增加经验值
				user.setBagCount(rule.getRuleValue() * Constant.BAG_S);//增加卡包容量
			}
			//设置用户组
			for(UserGroup group:InitService.userGroups){
				if(user.getExp() >= group.getExpLowerLimit() && user.getExp() <= group.getExpUperLimit()){
					user.setGroupId(group.getGroupId());
					user.setGroupName(group.getGroupName());
					break;
				}
			}
			
			userDAO.addUser(user);
			int userId = userDAO.getIncreamentId();
			if(user.getType() == Constant.REGISTER_BY_EMAIL){
				//生成唯一激活码
				UUID uuid = UUID.randomUUID();
				String activeCode = uuid.toString().replaceAll("-", "");
				//存储激活码
				addActiveCode(user.getEmail(),activeCode);
				//发送激活邮件
				sendEmail(user.getEmail(),user.getUsername(),Constant.EMAIL_URL,activeCode);
			}
			
			//注册成功后，添加默认详细信息
			UserInfo info = new UserInfo();
			info.setUserId(userId);
			if(user.getMemberType() == Constant.MEMBER_TYPE_SELLER){
				info.setName(user.getRealName());
				info.setWorkPlace(user.getAddress());
			}
			userDAO.addUserInfo(info);
			
		} catch (Exception e) {
			throw e;
		}
		
		return true;
	}
	
	private void sendEmail(String email,String username,String url,String activeCode){
		HtmlEmail hEmail = new HtmlEmail();       
        //email.setTLS(true); //是否TLS校验，，某些邮箱需要TLS安全校验，同理有SSL校验  
		hEmail.setDebug(true);  
        //email.setSSL(true);          
		hEmail.setHostName("smtp.163.com");   
		hEmail.setAuthenticator(new DefaultAuthenticator("hqccrazy@163.com", "hqc12345"));  
        try{    
        	hEmail.setFrom("hqccrazy@163.com"); //发送方,这里可以写多个  
        	hEmail.addTo(email); // 接收方  
        	hEmail.setCharset("utf-8");  
        	hEmail.setSubject("请激活您的账号，完成注册"); // 标题  
        	StringBuffer sb = new StringBuffer();
        	url = url + activeCode;
        	sb.append("<html>亲爱的"+username+"<br>");
        	sb.append("欢迎加入家在曼城！<br>");
        	sb.append("请点击下面链接完成注册：<br>");
        	sb.append("<a href='"+url+"'>"+url+"</a><br>");
        	sb.append("如果以上链接无法点击，请将上面的地址复制到你的浏览器(如IE)的地址栏进入家在曼城。<br><br>");
        	sb.append("--家在曼城<br>");
        	sb.append("(这是一封自动产生的email，请勿回复。)</html>");
        	hEmail.setHtmlMsg(sb.toString());// 内容 
        	hEmail.send();  
        	System.out.println("发送成功");  
        } catch (EmailException e) {    
            Log.error(e.getMessage(), e);
        }     
	}
	
//	public String getPasswordByEmailOrPhone(String info) throws Exception{
//		if(info.contains("@")){
//			//按照邮箱找回
//			if(userDAO.isRegisteredEmail(info)){
//				User user = userDAO.getUserByEmail(info);
//				return user.getPassword();
//			}
//		}else{
//			//按照手机号找回
//		}
//	}
	
	public Object changePassword(long userId,String oldPassword,String newPassword) throws Exception {
		Map<String,String> result = new HashMap<String,String>();
		result.put(Constant.SINGLE_RETURN,"true");
		
		if(null == oldPassword || "".equals(oldPassword)){
			return new ErrorMsg(Constant.MEMBER_REGISTER_PASSWORD_NULL,"密码不能为空！");
		}
		
		if(null == newPassword || "".equals(newPassword)){
			return new ErrorMsg(Constant.MEMBER_REGISTER_PASSWORD_NULL,"密码不能为空！");
		}
		
		User user = userDAO.getUserById(userId);
		
		String md5OldPass = MD5Util.fromStringToMD5(oldPassword);
		if(!md5OldPass.equals(user.getPassword())){
			return new ErrorMsg(Constant.MEMBER_LOGIN_PASSWORD_ERROR,"密码不正确！");
		}
		
		String newMd5Pass = MD5Util.fromStringToMD5(newPassword);
		userDAO.updatePass(userId, newMd5Pass);
		return result;
	}
	
	public Object addOrUpdateUser(User user) throws Exception{
		if(null != user){
			
			DateTime dt = new DateTime();
			String registerTime = dt.toString("yyyy-MM-dd hh:mm:ss");
			user.setRegisterTime(registerTime);
			
			if(user.getUserId() > 0){//更新
				User u1 = userDAO.getUserById(user.getUserId());
				if(u1.getUsername() != null && !u1.getUsername().equals(user.getUsername())){
					//验证用户名唯一性
					User u = userDAO.getUserByUsername(user.getUsername());
					if(null != u && u.getUserId() > 0){
						return new ErrorMsg(Constant.MEMBER_REGISTER_USERNAME_EXIST,"用户名已经被占用！");
					}
				}
				if(u1.getPhone() != null && !u1.getPhone().equals(user.getPhone())){
					//验证手机号是否已经使用过
					if(userDAO.isRegisteredPhone(user.getPhone())){
						return new ErrorMsg(Constant.MEMBER_REGISTER_PHONE_EXIST,"手机号已经被占用！");
					}
				}
				if(u1.getEmail() != null && !u1.getEmail().equals(user.getEmail())){
					if(null != user.getEmail() && !"".equals(user.getEmail())){
						//验证邮箱是否已经注册过
						if(userDAO.isRegisteredEmail(user.getEmail())){
							return new ErrorMsg(Constant.MEMBER_REGISTER_EMAIL_EXIST,"该邮箱已经被占用!");
						}
					}
				}
				if(!u1.getPassword().equals(user.getPassword())){
					//对密码进行加密：
					user.setPassword(MD5Util.fromStringToMD5(user.getPassword()));
				}
				int v = user.getCouponBag() - u1.getCouponBag();//更新后的卡包基数差值
				int count = userDAO.getBagCount(user.getUserId()) + v;
				//update
				user.setBagCount(count);
				userDAO.updateUser(user);
			}else{
				//验证用户名唯一性
				User u = userDAO.getUserByUsername(user.getUsername());
				if(null != u && u.getUserId() > 0){
					return new ErrorMsg(Constant.MEMBER_REGISTER_USERNAME_EXIST,"用户名已经被占用！");
				}
				if(null != user.getPhone() && !"".equals(user.getPhone())){
					//验证手机号是否已经使用过
					if(userDAO.isRegisteredPhone(user.getPhone())){
						return new ErrorMsg(Constant.MEMBER_REGISTER_PHONE_EXIST,"手机号已经被占用！");
					}
				}
				if(null != user.getEmail() && !"".equals(user.getEmail())){
					//验证邮箱是否已经注册过
					if(userDAO.isRegisteredEmail(user.getEmail())){
						return new ErrorMsg(Constant.MEMBER_REGISTER_EMAIL_EXIST,"该邮箱已经被占用!");
					}
				}
				//对密码进行加密：
				user.setPassword(MD5Util.fromStringToMD5(user.getPassword()));
				
				//insert
				
				userDAO.addUser(user);
			}
			
		}
		return true;
	}
	
	private void addActiveCode(String email,String activeCode) throws Exception{
		userDAO.addActiveCode(email, activeCode);
	}
	
	public User confirmUser(String activeCode) throws Exception{
		User user = userDAO.getUserByActiveCode(activeCode);
		//更新用户状态
		userDAO.setActived(user.getUserId());
		
		return user;
	}
	
	public Object login(String username,String password) throws Exception{
		if(null == username || "".equals(username)){
			return new ErrorMsg(Constant.MEMBER_LOGIN_USERNAME_NULL,"用户名为空！");
		}
		if(null == password || "".equals(password)){
			return new ErrorMsg(Constant.MEMBER_LOGIN_PASSWORD_NULL,"用户密码为空！");
		}
		
		User user = userDAO.getUserByUsername(username);
		if(null == user){
			return new ErrorMsg(Constant.MEMBER_LOGIN_USER_NOT_EXIST,"用户名不正确！");
		}
		String newPass = MD5Util.fromStringToMD5(password);
		if(!newPass.equals(user.getPassword())){
			return new ErrorMsg(Constant.MEMBER_LOGIN_PASSWORD_ERROR,"密码不正确！");
		}
		
		return user;
	}
	
	public void addUserInfo(UserInfo info) throws Exception{
		userDAO.addUserInfo(info);
	}
	
	public void updateUserInfo(UserInfo info) throws Exception{
		userDAO.updateUserInfo(info);
	}
	
	public UserInfo getUserInfo(long userId) throws Exception{
		return userDAO.getUserInfo(userId);
	}
	
	public void addFriends(long userId, String userName, String[] friends) throws Exception{
		//userDAO.addFriends(userId, friends);
		for(String friend : friends){
			long friendId = Long.parseLong(friend);
			addFriend(userId, userName, friendId, "");
		}
	}
	
	public void addFriend(long userId, String userName, long friendId, String message) throws Exception{
		String status = friendDAO.getFriendStatus(userId, friendId);	//当前两人的好友状态
		int statusInt = Integer.parseInt(status);
		if(statusInt == Constant.USER_FRIEND_IRRELEVANT){	//无关系，则新增一条好友申请
			userDAO.addFriend(userId, friendId, message);
			//增加系统提醒告知对方
			DateTime dt = new DateTime();
			String time = dt.toString("yyyy-MM-dd HH:mm:ss");
			Message msg = new Message();
			msg.setFromUserId(0);//系统发出
			msg.setFromUserName("系统提醒");
			msg.setMessage("会员 "+ userName + " 在 " + time + "申请成为您的好友");
			msg.setMessageType(Constant.MESSAGE_TYPE_SYSTEM_REMIND);
			msg.setSendTime(time);
			User user = userDAO.getUserById(friendId);
			msg.setToUserId(friendId);
			msg.setToUserName(user.getUsername());
			msg.setSendType(Constant.MESSAGE_TYPE_SYSTEM_REMIND);
			
			messageDAO.addMessage(msg);
		}else if(statusInt == Constant.USER_FRIEND_REFUSE){	//被拒绝，则更新拒绝的申请记录
			userDAO.updateFriend(userId, friendId, message);
			//增加系统提醒告知对方
			DateTime dt = new DateTime();
			String time = dt.toString("yyyy-MM-dd HH:mm:ss");
			Message msg = new Message();
			msg.setFromUserId(0);//系统发出
			msg.setFromUserName("系统提醒");
			msg.setMessage("会员 "+ userName + " 在 " + time + "再次申请成为您的好友");
			msg.setMessageType(Constant.MESSAGE_TYPE_SYSTEM_REMIND);
			msg.setSendTime(time);
			User user = userDAO.getUserById(friendId);
			msg.setToUserId(friendId);
			msg.setToUserName(user.getUsername());
			msg.setSendType(Constant.MESSAGE_TYPE_SYSTEM_REMIND);
			
			messageDAO.addMessage(msg);
		}
	}
	
	public PageModel getAllowedFriends(long userId,PageModel model) throws Exception{
		return friendDAO.getAllowedFriends(userId, 1, model);
	}
	
	public List<Friend> getApplyedFriends(long userId) throws Exception{
		return userDAO.getFriends(userId, 0);
	}
	
	public PageModel getApplyedFriends(long userId,PageModel model) throws Exception{
		return friendDAO.getFriends(userId, 0, model);
	}
	
	public void setFriend(long userId,long friendId,int status) throws Exception{
		userDAO.setFriend(userId, friendId,status);
	}
	
	public List<UserInfo> getUsersByHomeTown(String homeTown,long userId) throws Exception{
		List<UserInfo> list = userDAO.getUserInfosByHomeTown(homeTown);
		if(userId > 0){
			//获取好友信息
			List<Friend> friends = userDAO.getMyFriends(userId);
			//如果是登录用户，则需要获取该用户已经获取的好友状态
			if(null != list && !list.isEmpty()){
				if(null != friends && !friends.isEmpty()){
					for(UserInfo info:list){
						for(Friend f:friends){
							if(info.getUserId() == f.getFriendId()){
								info.setFriendStatus(f.getStatus());
								break;
							}
						}
					}
				}
				 
			}
		}
		return list;
	}
	
	public List<UserInfo> getUsersBySchool(int school,long userId) throws Exception{
		List<UserInfo> list = userDAO.getUserInfosBySchool(school);
		if(userId > 0){
			//获取好友信息
			List<Friend> friends = userDAO.getMyFriends(userId);
			//如果是登录用户，则需要获取该用户已经获取的好友状态
			if(null != list && !list.isEmpty()){
				if(null != friends && !friends.isEmpty()){
					for(UserInfo info:list){
						for(Friend f:friends){
							if(info.getUserId() == f.getFriendId()){
								info.setFriendStatus(f.getStatus());
								break;
							}
						}
					}
				}
				 
			}
		}
		return list;
	}
	
	public void updateHeader(String header,long userId) throws Exception{
		userDAO.updateHeader(header, userId);
	}
	
	public PageModel gePagedUsers(PageModel model,String search) throws Exception{
		return userDAO.getPagedUsers(model, search);
	}
	
	public User getUserById(long userId) throws Exception{
		return userDAO.getUserById(userId);
	}
	
	public User getUserByUsername(String username) throws Exception{
		return userDAO.getUserByUsername(username);
	}
	
	public void deleteUser(long userId) throws Exception{
		userDAO.deleteUser(userId);
	}
	
	public void addCollege(long userId,long infoId,int type) throws Exception{
		userDAO.addCollege(userId, infoId, type);
	}
	
	public PageModel getUserColleges(long userId,int moduleType,PageModel model) throws Exception{
		
		switch(moduleType){
			case Constant.COMM_ADDRESS_INFO_MODULE:
				return liveAddressDAO.getCollegeAddresses(userId, moduleType,model);
			case Constant.COMM_BOOK_INFO_MODULE:
			case Constant.COMM_TICKET_INFO_MODULE:
				return bookFoodDAO.getCollegeInfos(userId, moduleType,model);
			case Constant.COMM_COUPON_INFO_MODULE:
				return couponDAO.getCollegeInfos(userId, moduleType,model);
			case Constant.COMM_RENT_INFO_MODULE:
				return rentDAO.getCollegeRents(userId, moduleType,model);
			case Constant.COMM_SECONDARY_INFO_MODULE:
				return secondaryDAO.getCollegeSecondaries(userId, moduleType,model);
			case Constant.COMM_SIMPLE_INFO_MODULE:
				return liveSimpleDAO.getCollegeInfos(userId, moduleType,model);
			default:
				return null;
		}
		
	}
	
	public void deleteCollege(long userId,long infoId,int type) throws Exception{
		userDAO.deleteCollege(userId, infoId,type);
	}
	
	public int getCollegeCount(long userId,long infoId,int type) throws Exception{
		return userDAO.getCollegeCount(userId, infoId, type);
	}
	
	public List<UserInfo> getUserInfosByCityId(int cityId) throws Exception{
		return userDAO.getUserInfosByCityId(cityId);
	}
	
	public PageModel getUserInfosByCityId(PageModel pageModel,int cityId) throws Exception{
		return userInfoDAO.getUserInfosByCityId(pageModel, cityId);
	}

	public String checkFriend(long userId, long friendId) {
		
		String status = this.friendDAO.getFriendStatus(userId,friendId);
		if(status == null || "".equals(status)){
			status = "" + Constant.USER_FRIEND_IRRELEVANT;
		}
		return status;
	}
	
	public Object getStatistics(long userId){
		Map<String, Integer> rs = new HashMap<String, Integer>();
		int message = this.messageDAO.countMineMessage(userId);
		int topic = this.topicDAO.getMyTopicsCount(userId);
		int post = this.postDAO.getMyPostsCount(userId);
		/*int collection = 0;
		//遍历求取所有可收藏模块的收藏数目
		PageModel model = new PageModel();
		model.setNumPerPage(1);
		for(int i=1; i<=8; i++){
			try {
				PageModel tempModel = getUserColleges(userId, i, model);
				System.out.println("collection "+i+" is OK");
				if(tempModel != null){
					collection += tempModel.getTotalCount();
				}
			} catch (Exception e) {
				//e.printStackTrace();
			}
		}*/
		int collection = this.userDAO.getAllCollegeCount(userId);
		
		rs.put("message", message);
		rs.put("topic", topic);
		rs.put("post", post);
		rs.put("collection", collection);
		
		return rs;
	}

}
